import React from 'react';
import { RequestData } from '@ant-design/pro-table';
import { SortOrder } from 'antd/lib/table/interface';

import { omit, isArray, isFunction } from 'lodash';
import { createBrowserHistory, BrowserHistory } from 'history';
import { SelectProps } from 'antd';
import { DefaultOptionType as TreeSelectOptionProps } from 'rc-tree-select/lib/TreeSelect';
import { DefaultOptionType as SelectOptionProps } from 'rc-select/lib/Select';
import IconFont from '@component/IconFont';

/**
 * history 对象
 * @date 2022/9/9 - 03:34:26
 *
 * @type {*}
 */
export const history: BrowserHistory = createBrowserHistory();

// 导出消息中心
export { messageCenter, decoratorMessageCenter } from './MessageCenter';

/**
 * 处理高级表格axios转换
 * @date 2022/9/6 - 15:38:43
 * @params url {string} 请求url
 * @params params {Object} 请求参数
 * @returns {Promise<any>}
 */
export function proTableRequest(
  url: string,
  customParams: Record<string, any> = {}
): (
  params: {
    pageSize?: number;
    current?: number;
    keyword?: string;
  },
  sort: Record<string, SortOrder>,
  filter: Record<string, React.ReactText[] | null>
) => Promise<Partial<RequestData<any>>> {
  return async (
    params: {
      pageSize?: number;
      current?: number;
      keyword?: string;
    },
    sort: Record<string, SortOrder>,
    filter: Record<string, React.ReactText[] | null>
  ) => {
    const res = await $get(url, {
      pageSize: params.pageSize,
      pageNum: params.current,
      ...params,
      ...customParams,
    });
    const data = {
      ...res,
      data: res.rows,
      total: res.total,
      success: true,
    };
    return Promise.resolve<Partial<RequestData<any>>>(data);
  };
}

/**
 * 下载文件方法
 * @date 2022/9/6 - 15:38:33
 *
 * @async
 * @param {string} url
 * @param {{}} [params={}]
 * @returns {Promise<any>}
 */
export const downloadFile = async (url: string, params: {} = {}): Promise<any> => {
  const res = await $post(url, params, {
    responseType: 'blob',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
    },
  });
  const blob = new Blob([res], { type: 'application/vnd.ms-excel' });
  const link = document.createElement('a');
  document.body.appendChild(link);
  link.href = window.URL.createObjectURL(blob);
  link.click();
  document.body.removeChild(link);
  return res.status === 200;
};

/**
 * 转换参数为若依系统专用的
 * @date 2022/9/6 - 15:38:25
 *
 * @param {{ pageSize?: number; current?: number; keyword?: string }} [params={}]
 * @returns {{ pageSize: number; pageNum: number; current?: number; keyword?: string; }}
 */
export const convertPaging = (
  params: { pageSize?: number; current?: number; keyword?: string } = {}
): { pageSize: number; pageNum: number; current?: number; keyword?: string } => {
  return {
    ...params,
    pageSize: params.pageSize,
    pageNum: params.current,
  };
};

/**
 * 转换标签颜色回显为tag的颜色
 * @date 2022/9/6 - 15:38:15
 *
 * @param {('default' | 'success' | 'warning' | 'danger' | 'info' | 'primary')} color 若依后台颜色字符串
 * @return {String} 颜色字符标识
 */
export const convertTagColor = (
  color: 'default' | 'success' | 'warning' | 'danger' | 'info' | 'primary'
): string => {
  const map = new Map([
    ['default', 'default'],
    ['success', 'success'],
    ['warning', 'warning'],
    ['danger', 'error'],
    ['info', 'blue'],
    ['primary', 'cyan'],
  ]);
  return map.get(color);
};

/**
 * 保存数据时删除不需要的参数
 * @date 2022/9/6 - 15:38:03
 *
 * @param {{}} [params={}] 可编辑表格列数据
 * @returns {*}
 */
export const saveDataParams = (params: {} = {}): any => {
  return omit({ ...params }, [
    'updateTime',
    'params',
    'searchValue',
    'updateBy',
    'index',
    'createTime',
    'createBy',
  ]);
};

/**
 * 实现复制粘贴
 * @date 2022/9/6 - 15:37:48
 *
 * @export
 * @param {string} str 要复制的字符串
 * @param {() => void} [cb=() => {}] 回调函数
 * @returns {void) => void}
 */
export function copy(str: string, cb: () => void = () => {}): void {
  let transfer = document.createElement('input');
  document.body.appendChild(transfer);
  transfer.value = str; // 这里表示想要复制的内容
  transfer.focus();
  transfer.select();
  if (document.execCommand('copy')) {
    document.execCommand('copy');
  }
  transfer.blur();
  document.body.removeChild(transfer);
  cb();
}

/**
 * 将远程字典数据转换为antd-pro可用的
 * @date 2022/9/6 - 15:36:51
 *
 * @export
 * @param {Record<string, any>[]} list 远程列表数据
 * @returns {{}}
 */
export function convertDict(list: Record<string, any>[]): {} {
  const dict = {};
  list.forEach(d => {
    dict[d['dictType']] = {
      text: `${d['dictName']}(${d['dictType']})`,
    };
  });
  return dict;
}

/**
 * 将远程的树结构转成antd-pro 可用的
 * @date 2022/9/6 - 16:21:20
 *
 * @export
 * @param {Record<string, any>[]} list
 */
export function convertTree(list: Record<string, any>[]) {
  let tree: TreeSelectOptionProps[] = [];
  list &&
    list.forEach(d => {
      const child = d.children ? convertTree(d.children) : undefined;
      tree.push({
        label: d.label,
        value: d.id,
        children: child,
      });
    });
  return tree;
}

/**
 * 将远程的列表转为select可用
 * @date 2022/9/6 - 17:27:17
 *
 * @export
 * @param {Record<string, any>[]} list
 * @param {string} labelKey label 字段
 * @param {string} valueKey value 字段
 * @return {array} select option
 */
export function transToSelect(list: any[], labelKey: string, valueKey: string): Array<any> {
  const selectList: SelectOptionProps[] = [];
  list.forEach(d => {
    if (d[labelKey] && d[valueKey]) {
      const isChildren = d.children && isArray(d.children);
      selectList.push({
        label: `${d[labelKey]}: ${d[valueKey]}`,
        value: d[valueKey],
        children: isChildren ? transToSelect(d.children, labelKey, valueKey) : undefined,
      });
    }
  });
  return selectList;
}

/**
 * 构造树型结构数据
 * @param {*} data 数据源
 * @param {*} id id字段 默认 'id'
 * @param {*} parentId 父节点字段 默认 'parentId'
 * @param {*} children 子节点字段 默认 'children'
 */
export function handleTree(data: any[], id?: string, parentId?: string, children?: string) {
  let config: {
    id?: string;
    parentId?: string;
    childrenList?: string;
  } = {
    id: id || 'id',
    parentId: parentId || 'parentId',
    childrenList: children || 'children',
  };

  var childrenListMap = {};
  var nodeIds = {};
  var tree = [];

  for (let d of data) {
    let parentId = d[config.parentId];
    if (childrenListMap[parentId] == null) {
      childrenListMap[parentId] = [];
    }
    nodeIds[d[config.id]] = d;
    childrenListMap[parentId].push(d);
  }

  for (let d of data) {
    let parentId = d[config.parentId];
    if (nodeIds[parentId] == null) {
      tree.push(d);
    }
  }

  for (let t of tree) {
    adaptToChildrenList(t);
  }

  function adaptToChildrenList(o: { [x: string]: any }) {
    if (childrenListMap[o[config.id]] !== null) {
      o[config.childrenList] = childrenListMap[o[config.id]];
    }
    if (o[config.childrenList]) {
      for (let c of o[config.childrenList]) {
        adaptToChildrenList(c);
      }
    }
  }
  return tree;
}

/**
 * 获取自定义图标的列表
 * @date 2022/9/8 - 00:50:14
 *
 * @export
 */
export function translationIcon() {
  const iconsKey = [
    'system',
    'monitor',
    'tool',
    'guide',
    'user',
    'peoples',
    'tree-table',
    'tree',
    'post',
    'dict',
    'edit',
    'message',
    'log',
    'online',
    'job',
    'druid',
    'server',
    'redis',
    'redis-list',
    'build',
    'code',
    'swagger',
    'form',
    'logininfor',
  ];
  const opt: SelectProps<any>['options'] = [];
  iconsKey.forEach(d => {
    let temp = {
      label: (
        <>
          <IconFont name={d} /> {d}
        </>
      ),
      value: d,
    };
    opt.push(temp);
  });
  return opt;
}

/**
 * select转字典格式
 * @date 2022/9/14 - 21:40:49
 *
 * @export
 * @param {SelectProps<any>['options']} list
 */
export function selectToDict(list: SelectProps<any>['options']) {
  const temp = {};
  list.forEach(d => {
    temp[d.value] = {
      text: d.label,
    };
  });
  return temp;
}
